<template>
  <div style="width: 100%;position: relative">
    <div id="container" class="map"></div>
    <div class="search-box">
      <el-select v-if="isSearch" v-model="address" clearable placeholder="请输入关键词" :remote-method="remoteMethod"
                 filterable remote @change="currentSelect" class="one-text" size="default">
        <el-option v-for="(item, index) in areaList" :key="index" :label="item.district + item.name"
                   :value="item.district + item.name">
          <span>{{ item.district }}</span> <span>{{ item.name }}</span>
        </el-option>
      </el-select>
    </div>
  </div>
</template>

<script setup name="x-address-amap">
import { reactive, ref, toRefs, onMounted, nextTick, defineProps } from 'vue';
import AMapLoader from "@amap/amap-jsapi-loader";
const props = defineProps({
  addressClick: Function,
  isSearch: {
    type: Boolean,
    default: true
  }
})
onMounted(() => {
  window._AMapSecurityConfig = {
    securityJsCode: '600643e725e3027f706e927f94d2b00f',
  }
  initMap()
})

const state = reactive({
  map: null,
  placeSearch: null,
  autoComplete: null,
  marker: null,
  form: {
    address: '',
    lng: '',
    lat: '',
  },
  areaList: [],
  address: ''
})

const { areaList, address } = toRefs(state)

function initMap(arr) {
  AMapLoader.load({
    key: "641b66011e07bab69773905e0538b014",
    version: "2.0",
    plugins: ["AMap.ToolBar", "AMap.ControlBar", 'AMap.AutoComplete', 'AMap.PlaceSearch', 'AMap.Geocoder', 'AMap.Marker'],
  }).then((AMap) => {
    state.map = new AMap.Map('container', {
      viewMode: "3D",  //  是否为3D地图模式
      zoom: 15,
      center: arr,
      resizeEnable: true
    });
    // 地图放大缩小插件
    let toolBar = new AMap.ToolBar({
      position: {
        top: '120px',
        right: '51px'
      }
    })
    // 3D地图插件
    let controlBar = new AMap.ControlBar({
      position: {
        top: '20px',
        right: '20px',
      },
    });

    state.geoCoder = new AMap.Geocoder({
      city: '010', //城市设为北京，默认：“全国”
      radius: 1000 //范围，默认：500
    })

    // 正向地理编码
    state.geocoder = new AMap.Geocoder({
      city: state.address
    })

    state.autoComplete = new AMap.AutoComplete({ city: '全国' });

    state.map.on('click', (e) => { // 点击地图事件
      if (!e && !e.lnglat) {
        return
      }
      state.form.lng = e.lnglat.lng
      state.form.lat = e.lnglat.lat
      removeMarker() // 先删除地图上标记点
      setMapMarker() // 在添加新的标记点
    })
    state.map.addControl(toolBar);   // 添加右上角的放大缩小
    state.map.addControl(controlBar);   // 添加右上角的放大缩小
  }).catch((e) => {
    console.error(e);  //加载错误提示
  }).finally(() => {
    removeMarker()
    setMapMarker()
  })
}

function setMapMarker() {
  if (state.form.lng == '' && state.form.lat == '') {
    return
  }
  state.map.setFitView()
  state.marker = new AMap.Marker({
    map: state.map,
    position: [state.form.lng, state.form.lat],
  })
  toGetAddress()
  state.map.setFitView()
  state.map.add(state.marker)
}

function removeMarker() {
  if (state.marker) {
    state.map.remove(state.marker)
  }
}

function toGetAddress() {
  let lnglat = [state.form.lng, state.form.lat]
  state.geoCoder.getAddress(lnglat, (status, result) => {
    if (status === 'complete' && result.regeocode) {
      props.addressClick(result, state.form.lng, state.form.lat) // 返回位置信息以及经纬度
    }
  })
}

function remoteMethod(query) {
  if (query !== '') {
    setTimeout(() => {
      state.autoComplete.search(query, (status, result) => {
        state.areaList = result.tips
      })
    }, 500)
  } else {
    state.areaList = []
  }
}
function currentSelect(val) {
  if (!val) {
    return
  }
  toGetCoordinate(val)
}

function toGetCoordinate(address) {
  state.address = address;
  state.geocoder.getLocation(address, function (status, result) {
    if (status === 'complete' && result.info === 'OK') {
      initMap([result.geocodes[0].location.lng, result.geocodes[0].location.lat])
      state.form.lng = result.geocodes[0].location.lng
      state.form.lat = result.geocodes[0].location.lat
      state.form.address = result.geocodes[0].formattedAddress
    }
  })
  nextTick(function () {
    removeMarker()
    setMapMarker()
  })
}

function fixed(lng, lat) {
  initMap([lng, lat])
  state.form.lng = lng
  state.form.lat = lat
}


// 暴露方法
defineExpose({
  fixed,
  toGetCoordinate
});
</script>



<style scoped lang="less">
.map {
  width: 100%;
  height: 400px;
}

.search-box {
  position: absolute;
  z-index: 9;
  top: 20px;
  left: 20px;

  ::v-deep(.el-select) {
    width: 640px !important;
    border-radius: 50px;
    overflow: hidden;

    .el-input__wrapper {
      border-radius: 50px;
    }
  }
}
</style>
